package com.hu.common.util.comm;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.hu.common.domain.base.PublicPeriod;
import com.hu.common.domain.base.Result;
import com.hu.common.enums.PeriodEnum;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author 00355760
 * @功能： 计算时间段中文工具类
 * @版本： V1
 * @版权： 信息技术有限公司（http://www.mychery.com/）
 * @作者： 磐石战队开发组  00355760
 * @日期： 2024/10/16 13:38
 */
public class PeriodUtil {

    private static final String DATE_PATTERN = "yyyy-MM-dd HH:mm:ss";
    /** 时间段向前推的周期数，为了计算增长率，多查一个周期 */
    private static int TIME_BACK = 7;

    /**
     * 根据给定的年份和向前推的年份数生成年度标题和时间范围。
     *
     * @param year 年份
     * @return 包含年度标题和时间范围的JSON对象
     */
    public static Result generateYearPeriods(int year) {
        List<String> titles = new ArrayList<>();
        List<PublicPeriod> periods = new ArrayList<>();

        LocalDate startDate = DateUtil.beginOfYear(DateUtil.parse(year + "-01-01")).toLocalDateTime().toLocalDate();
        LocalDate endDate = DateUtil.endOfYear(DateUtil.parse(year + "-12-31")).toLocalDateTime().toLocalDate();

        for (int i = 0; i < TIME_BACK; i++) {
            LocalDateTime currentStart = startDate.atStartOfDay();
            LocalDateTime currentEnd = endDate.atStartOfDay().withHour(23).withMinute(59).withSecond(59);

            if (year == LocalDate.now().getYear() && i == 0) {
                currentEnd = LocalDateTime.now().minusDays(1).withHour(23).withMinute(59).withSecond(59);
            }

            titles.add(0, currentStart.getYear() + "年");
            periods.add(0, new PublicPeriod(currentStart.format(DateTimeFormatter.ofPattern(DATE_PATTERN)), currentEnd.format(DateTimeFormatter.ofPattern(DATE_PATTERN))));

            startDate = startDate.minusYears(1);
            endDate = endDate.minusYears(1);
        }

        return new Result(titles, periods);
    }

    /**
     * 根据给定的年份、季度和向前推的季度数生成季度标题和时间范围。
     *
     * @param year    年份
     * @param quarter 季度
     * @return 包含季度标题和时间范围的JSON对象
     */
    public static Result generateQuarterPeriods(int year, int quarter) {
        List<String> titles = new ArrayList<>();
        List<PublicPeriod> periods = new ArrayList<>();

        LocalDate startDate = DateUtil.beginOfMonth(DateUtil.parse(year + "-01-01")).toLocalDateTime().toLocalDate().plusMonths((quarter - 1) * 3L);
        LocalDate endDate = DateUtil.endOfMonth(DateUtil.parse(year + "-01-01")).toLocalDateTime().toLocalDate().plusMonths(quarter * 3L - 1);

        for (int i = 0; i < TIME_BACK; i++) {
            LocalDateTime currentStart = startDate.atStartOfDay();
            LocalDateTime currentEnd = endDate.atStartOfDay().withHour(23).withMinute(59).withSecond(59);

            if (year == LocalDate.now().getYear() && quarter == getQuarter(LocalDate.now().getMonthValue()) && i == 0) {
                currentEnd = LocalDateTime.now().minusDays(1).withHour(23).withMinute(59).withSecond(59);
            }

            titles.add(0, currentStart.getYear() + "年" + getQuarter(currentStart.getMonthValue()) + "季度");
            periods.add(0, new PublicPeriod(currentStart.format(DateTimeFormatter.ofPattern(DATE_PATTERN)), currentEnd.format(DateTimeFormatter.ofPattern(DATE_PATTERN))));

            Date endofDate = Date.from(endDate.minusMonths(3).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());

            startDate = startDate.minusMonths(3);
            endDate = DateUtil.endOfMonth(endofDate).toLocalDateTime().toLocalDate();
        }

        return new Result(titles, periods);
    }

    /**
     * 根据给定的年份、月份和向前推的月数生成月标题和时间范围。
     *
     * @param year  年份
     * @param month 月份
     * @return 包含月标题和时间范围的JSON对象
     */
    public static Result generateMonthPeriods(int year, int month) {
        List<String> titles = new ArrayList<>();
        List<PublicPeriod> periods = new ArrayList<>();

        LocalDate startDate = DateUtil.beginOfMonth(DateUtil.parse(year + "-" + month + "-01")).toLocalDateTime().toLocalDate();
        LocalDate endDate = DateUtil.endOfMonth(DateUtil.parse(year + "-" + month + "-01")).toLocalDateTime().toLocalDate();

        for (int i = 0; i < TIME_BACK; i++) {

            LocalDateTime currentStart = startDate.atStartOfDay();
            LocalDateTime currentEnd = endDate.atStartOfDay().withHour(23).withMinute(59).withSecond(59);

            if (year == LocalDate.now().getYear() && month == LocalDate.now().getMonthValue() && i == 0) {
                currentEnd = LocalDateTime.now().minusDays(1).withHour(23).withMinute(59).withSecond(59);
            }

            titles.add(0, currentStart.getYear() + "年" + currentStart.getMonthValue() + "月");
            periods.add(0, new PublicPeriod(currentStart.format(DateTimeFormatter.ofPattern(DATE_PATTERN)), currentEnd.format(DateTimeFormatter.ofPattern(DATE_PATTERN))));

            Date endofDate = Date.from(endDate.minusMonths(1).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());

            startDate = startDate.minusMonths(1);
            endDate = DateUtil.endOfMonth(endofDate).toLocalDateTime().toLocalDate();
        }

        return new Result(titles, periods);
    }

    /**
     * 根据给定的年份、周数和向前推的周数生成周标题和时间范围。
     *
     * @param year 年份
     * @param week 周数
     * @return 包含周标题和时间范围的JSON对象
     */
    public static Result generateWeekPeriods(int year, int week) {
        List<String> titles = new ArrayList<>();
        List<PublicPeriod> periods = new ArrayList<>();

        LocalDate startDate = DateUtil.beginOfWeek(DateUtil.parse(year + "-01-01")).toLocalDateTime().toLocalDate().plusWeeks(week - 1);
        LocalDate endDate = DateUtil.endOfWeek(DateUtil.parse(year + "-01-01")).toLocalDateTime().toLocalDate().plusWeeks(week - 1);

        for (int i = 0; i < TIME_BACK; i++) {
            LocalDateTime currentStart = startDate.atStartOfDay();
            LocalDateTime currentEnd = endDate.atStartOfDay().withHour(23).withMinute(59).withSecond(59);

            if (year == LocalDate.now().getYear() && week == (LocalDate.now().getDayOfYear() / 7 + 1) && i == 0) {
                currentEnd = LocalDateTime.now().minusDays(1).withHour(23).withMinute(59).withSecond(59);
            }

            titles.add(0, currentStart.getYear() + "/" + currentStart.getMonthValue() + "/" + currentStart.getDayOfMonth()
                    + "-" + currentEnd.getYear() + "/" + currentEnd.getMonthValue() + "/" + currentEnd.getDayOfMonth());
            periods.add(0, new PublicPeriod(currentStart.format(DateTimeFormatter.ofPattern(DATE_PATTERN)), currentEnd.format(DateTimeFormatter.ofPattern(DATE_PATTERN))));

            startDate = startDate.minusDays(7);
            endDate = endDate.minusDays(7);

        }
        return new Result(titles, periods);
    }

    /**
     * 根据当前月获取当前季度
     *
     * @param month
     * @return
     */
    private static int getQuarter(int month) {
        if (month >= 1 && month <= 3) {
            return 1;
        } else if (month >= 4 && month <= 6) {
            return 2;
        } else if (month >= 7 && month <= 9) {
            return 3;
        } else {
            return 4;
        }
    }

    /**
     * 根据给定的周期、年份、周期值和向前推的周期次数生成周期标题和时间范围。
     *
     * @param periodEnum
     * @param year
     * @param periodValue
     * @param periodTimes
     * @return
     */
    public static Result generatePeriods(PeriodEnum periodEnum, Integer year, Integer periodValue, Integer periodTimes) {

        if (ObjectUtil.hasNull(year, periodValue)) {
            throw new IllegalArgumentException("周期值输入有误：year:" + year + ",periodValue:" + periodValue);
        }

        TIME_BACK = periodTimes;
        if (PeriodEnum.YEAR.equals(periodEnum)) {
            if (NumberUtil.equals(periodValue, year)) {
                return PeriodUtil.generateYearPeriods(year);
            } else {
                throw new IllegalArgumentException("年份与周期值应保持一致!");
            }
        } else if (PeriodEnum.QUARTER.equals(periodEnum)) {
            if (periodValue >= 1 && periodValue <= 4) {
                return PeriodUtil.generateQuarterPeriods(year, periodValue);
            } else {
                throw new IllegalArgumentException("季度只能为1-4!");
            }
        } else if (PeriodEnum.MONTH.equals(periodEnum)) {
            if (periodValue >= 1 && periodValue <= 12) {
                return PeriodUtil.generateMonthPeriods(year, periodValue);
            } else {
                throw new IllegalArgumentException("月度只能为1-12!");
            }
        } else {
            if (periodValue >= 1 && periodValue <= 53) {
                return PeriodUtil.generateWeekPeriods(year, periodValue);
            } else {
                throw new IllegalArgumentException("周度不合法!");
            }
        }
    }
}
